<template>
  <div class="h-auto w-[968px] mt-[124px] pb-10 -translate-x-1">
    <div v-show="panelStore.currentSections.length" ref="pageContainer" class="relative"></div>
    <div
      class="h-full page-container mt-1 ml-1 w-[960px] border-base-card rounded after:rounded flex justify-center items-center bg-background-01 black:bg-background-01-dark text-text-01 black:text-text-01-dark"
      v-show="!panelStore.currentSections.length"
      v-loading="loading"
    >
      {{ loading ? '' : '暂无数据' }}
    </div>
  </div>
</template>
<script setup lang="ts">
import { computed, ref, createApp, nextTick, onMounted } from 'vue'
import { deleteSection, getPanel, insertSection, updateSection } from '../services/chat-api'
import { usePanelStore } from '@/stores/panel'
import Murri from 'muuri'
import CardContainer from './CardContainer.vue'
import { ElMessage } from 'element-plus'
import { getEventBus } from '@/common/services/chat-event-bus'
import type { Section } from '@/common/models/recommend-result'
import trackEventDirective from '@/common/directives/track'
import { ERRORTYPE } from '@/common/config/const'

const {
  sectionSortEventBus,
  sectionInsertEventBus,
  updateViewEventBus,
  sectionOperatorEventBus,
  pageChangeEventBus,
  sectionUpdateEventBus
} = getEventBus()

const panelStore = usePanelStore()
const currentPanel = computed(() => panelStore.currentPanel)

const pageContainer = ref<HTMLElement | null>(null)

const grid = ref<Murri | null>(null)

const loading = ref(false)

const noData = ref(false)

const pageCreator = async (newPid: string) => {
  loading.value = true
  const pid = newPid
  try {
    grid.value = new Murri(pageContainer.value!, {
      items: '.card',
      dragEnabled: false,
      layout: {
        fillGaps: false
      }
    })
    const res = await getPanel(newPid)
    console.log({res});
    
    if (pid !== currentPanel.value?.id) return

    // 组件实例创建 & 添加到布局
    if (res && res.sections && res.sections.length) {
      noData.value = false
      await nextTick()
      res.sections.forEach((section) => {
        const { compVm, compApp, gridItem } = renderComponent(section)
        panelStore.addSectionInfo(section, compApp, compVm, gridItem)
        updateView()
      })
      loading.value = false
      return
    }
    panelStore.setSections([])
  } catch (error) {
    window.f10log(ERRORTYPE.AJAX, `页面渲染失败：${error}`, error)
  }
  loading.value = false
  noData.value = true
}

onMounted(() => {
  if (currentPanel.value) {
    pageCreator(currentPanel.value.id)
  }
})

sectionSortEventBus.on(({ newIndex, oldIndex }) => {
  grid.value?.move(oldIndex!, newIndex!)
})

function resetPageStatus() {
  // 实例销毁 重置
  panelStore.clearSectionInfo()
  grid.value?.destroy()
}

// 监听：页面切换
pageChangeEventBus.on(({ id }) => {
  window.weblog.report({
    id: 'thspc_f10_copilot',
    action: 'show',
    logmap: {
      pid: id
    }
  })
  if (id) {
    nextTick(() => {
      resetPageStatus()
      pageCreator(id)
    })
  }
})

// 监听：插入至页面
sectionInsertEventBus.on(async ({ section, askId, index }) => {
  try {
    const newSection = await insertSection(askId, panelStore.currentPanel!.id, section.id, index)
    const { compVm, compApp, gridItem } = renderComponent(newSection)
    panelStore.addSectionInfo(newSection, compApp, compVm, gridItem)
    ElMessage.success('插入成功！')
    await nextTick()
    setTimeout(() =>
      compVm.$el.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' })
    )
  } catch (error) {
    window.f10log(ERRORTYPE.AJAX, `插入卡片失败：${error}`, error)
    ElMessage.error('插入失败！请稍后重试！')
  }
})

// 监听：同步至页面
sectionUpdateEventBus.on(async ({ section, askId }) => {
  try {
    await updateSection(askId, section.id, section.from!)
    const currentSectionInfo = panelStore.getSectionInfo(section.from!)
    if (!currentSectionInfo) {
      ElMessage.error('不是本页面模块，无法同步！')
      return
    }

    Object.assign(currentSectionInfo?.section!, section, { id: currentSectionInfo.section?.id })
    currentSectionInfo?.cardVm.$el.scrollIntoView({
      behavior: 'smooth',
      block: 'center',
      inline: 'center'
    })
    await nextTick()
    updateView()
    ElMessage.success('同步成功')
  } catch (error) {
    window.f10log(ERRORTYPE.AJAX, `同步卡片失败：${error}`, error)
    ElMessage.error('同步失败！请稍后重试！')
  }
})

function renderComponent(section: Section) {
  const sectionRef = ref(section)
  const el = document.createElement('div')
  const compApp = createApp(CardContainer, { section: sectionRef.value })
  compApp.directive('track', trackEventDirective)
  const compVm = compApp.mount(el) as InstanceType<typeof CardContainer>
  const gridItem = grid.value!.add(compVm.$el)[0]
  return { compVm, compApp, gridItem }
}

function updateView() {
  const cardEleList = grid.value?.getItems()
  console.log({cardEleList});
  
  grid.value?.refreshItems(cardEleList, true)
  grid.value?.layout()
}

// 监听：模块操作
sectionOperatorEventBus.on(async ({ id, section }) => {
  // 卡片删除
  if (id === 'card_delete' && section) {
    try {
      await deleteSection(section.pid, section.id)
      panelStore.removeSectionInfo(section.id)
      updateView()
      ElMessage.success('删除成功!')
    } catch (error) {
      window.f10log(ERRORTYPE.AJAX, `删除卡片失败：${error}`, error)
      ElMessage.error('删除失败！请稍后重试！')
    }
  }
})

updateViewEventBus.on(() => {
  console.log('updateView')
  updateView()
})
</script>
<style lang="less" scoped>
.page-container {
  min-height: calc(100vh - 194px);
}
</style>
